package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.aliyuncs.utils.StringUtils;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.exception.BusinessException;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MovementService {

    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @DubboReference
    private MovementApi movementApi;
    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 发布动态
     * @param movement
     * @param imageContent
     */
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1,判断发布的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        //2,获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //3,将文件上传到阿里云，获取请求路径
        ArrayList<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        //4,将数据封装到Movement对象
        movement.setUserId(userId);
        movement.setMedias(medias);
        //5,调用api完成发布动态
        movementApi.publish(movement);
    }

    /**
     * 查询好友动态功能
     * @param userId
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        //根据用户id，调用api查询个人动态内容
        PageResult pr = movementApi.findByUserId(userId,page,pagesize);
        //获取pageresult中的item列表
        List<Movement> items = (List<Movement>)pr.getItems();
        log.info("items = {}",items.toString());
        //非空判断
        if (items == null){
            return pr;
        }
        //循环数据列表
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            //一个movement构建一个vo对象
            MovementsVo vo = MovementsVo.init(userInfo, item);
            //log.info(vo.toString());
            log.info("vo ======================{}",vo.toString());
            vos.add(vo);
        }
        //构建返回值
        pr.setItems(vos);
        return pr;
    }

    /**
     * 查询好友动态
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        //获取当前用户id
        Long userId = UserHolder.getUserId();
        //查询数据列表
        List<Movement> items = movementApi.findMovements(userId,page,pagesize);
        //非空判断
        return getPageResult(page, pagesize, items);
    }

    private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> items) {
        if (CollUtil.isEmpty(items)){
            return new PageResult();
        }
        return getMethodVO(page, pagesize, items);
    }

    private PageResult getMethodVO(Integer page, Integer pagesize, List<Movement> items) {
        //获取好友用户id
        List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);
        //循环数据列表
        Map<Long, UserInfo> userMaps = userInfoApi.findByIds(userIds, null);
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            //构建vo对象
            UserInfo userInfo = userMaps.get(item.getUserId());
            MovementsVo vo = MovementsVo.init(userInfo, item);
            vos.add(vo);
        }
        log.info("vos ==========================" + vos.toString());
        //构建返回值
        return new PageResult(page, pagesize,0l,vos);
    }

    /**
     * 查询推荐动态
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
        log.info("page = {},pagesize = {}",page,pagesize);
        /*PageResult pr = new PageResult();
        pr.setPage(page);
        pr.setPagesize(pagesize);*/
        //从redis中获取推荐数据
        String redisKey = Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        List<Long> pidList = null;
        //判断推荐数据是否存在
        //List<Movement> list = Collections.EMPTY_LIST;
        List<Movement> movements = new ArrayList<>();
        if (StringUtils.isEmpty(redisValue)) {
            //如果不存在，随机构造10条动态数据
            movements = movementApi.randomMovements(pagesize);
        }else {
            //将redis数据进行分页获取数据
            String[] pidStrArr = redisValue.split(",");
            //需要分页的数据不够
            //分页的起始下标有没有超过数组的长度
            int startIndex = (page - 1)*pagesize;
            if (startIndex < pidStrArr.length){//不越界
                pidList = Arrays.stream(pidStrArr).skip(startIndex).limit(pagesize)
                        .map(s -> Long.valueOf(s)).collect(Collectors.toList());
            }
            movements = movementApi.findMovementsByPids(pidList);
        }

        return getMethodVO(page,pagesize,movements);
    }

    /**
     * 根据id查询动态
     * @param movementId 动态id
     * @return MovementsVo
     */
    public MovementsVo findMovementById(String movementId) {
        Movement movement = movementApi.findMovementById(movementId);
        if(movement == null) {
            return null;
        }else {
            UserInfo userInfo = userInfoApi.findById(movement.getUserId());
            return MovementsVo.init(userInfo,movement);
        }
    }
}
